"""
无码提取器模块 - 函数式设计
专门处理无码类型视频的识别、提取和验证

作者: Claude  
创建时间: 2024-09-14
"""

import re
from typing import Optional, Tuple, Dict, Any, List
from functools import partial
from datetime import datetime

try:
    from config.patterns import pattern_config
except ImportError:
    import sys
    import os
    sys.path.append(os.path.dirname(os.path.dirname(__file__)))
    from config.patterns import pattern_config


def extract_uncensored_id_with_pattern(filename: str, pattern: str) -> Optional[str]:
    """
    使用指定模式提取无码ID - 纯函数设计
    
    :param filename: 文件名
    :param pattern: 正则表达式模式
    :return: 提取的ID或None
    """
    try:
        match = re.search(pattern, filename, re.IGNORECASE)
        if match:
            groups = match.groups()
            if len(groups) == 1:
                # 标准数字格式：只有一个组
                return groups[0]
            elif len(groups) == 2:
                # 系列名格式：组合系列名和数字
                series_name, number = groups
                return f"{series_name}-{number}"
            else:
                # 默认返回第一个组
                return groups[0]
    except Exception:
        pass
    return None




def is_valid_uncensored_id(uncensored_id: str) -> bool:
    """
    验证无码ID的有效性 - 支持数字格式和系列名格式
    
    :param uncensored_id: 无码ID
    :return: 是否有效
    """
    if not uncensored_id:
        return False
    
    # 检查是否为系列名格式（如 HEYZO-2150）
    series_pattern = r'^(HEYZO|CARIBBEANCOM|1PON|10MUSUME)-\d+$'
    if re.match(series_pattern, uncensored_id, re.IGNORECASE):
        return True
    
    # 检查是否为标准数字格式
    parts = None
    if '_' in uncensored_id:
        parts = uncensored_id.split('_')
    elif '-' in uncensored_id:
        parts = uncensored_id.split('-')
    
    if not parts or len(parts) != 2:
        return False
    
    first_part, second_part = parts
    
    # 验证两个部分都是数字
    if not (first_part.isdigit() and second_part.isdigit()):
        return False
    
    # 第一部分通常是6位数字
    if len(first_part) != 6:
        return False
        
    # 第二部分通常是3位数字
    if len(second_part) != 3:
        return False
    
    # 数字不能全为0
    if first_part == "0" * len(first_part) or second_part == "0" * len(second_part):
        return False
    
    return True


def detect_uncensored_type(filename: str) -> Tuple[bool, Optional[str]]:
    """
    检测是否为无码类型并提取ID
    
    :param filename: 清理后的文件名
    :return: (是否为无码, 提取的ID)
    """
    uncensored_patterns = pattern_config.get_uncensored_patterns()
    
    # 按优先级尝试每个模式
    for pattern_config_item in uncensored_patterns:
        extracted_id = extract_uncensored_id_with_pattern(filename, pattern_config_item.pattern)
        
        if extracted_id and is_valid_uncensored_id(extracted_id):
            return True, extracted_id
    
    return False, None


def extract_uncensored_metadata(filename: str) -> Dict[str, Any]:
    """
    提取无码视频的元数据信息
    
    :param filename: 文件名
    :return: 元数据字典
    """
    metadata = {
        'has_subtitle': False,
        'cd_number': None,
        'is_4k': False,
        'quality_info': None,
        'studio_info': None
    }
    
    filename_upper = filename.upper()
    
    # 检测字幕标记
    metadata['has_subtitle'] = bool(re.search(r'[-_]C(?:\.|$)', filename_upper))
    
    # 检测4K标记
    metadata['is_4k'] = bool(re.search(r'[-_]4K', filename_upper))
    
    # 检测CD分段信息
    # 只检测明确的CD标记，避免误判主要ID中的数字
    cd_match = re.search(r'[-_]CD(\d+)', filename_upper)
    if cd_match:
        cd_num = int(cd_match.group(1))
        if 1 <= cd_num <= 20:  # 合理范围
            metadata['cd_number'] = cd_num
    
    # 检测质量信息
    quality_patterns = ['FHD', '4K', 'HD']
    for quality in quality_patterns:
        if quality in filename_upper:
            metadata['quality_info'] = quality
            break
    
    
    # 检测制作商信息（常见的1pon等）
    studio_patterns = ['1PON', 'CARIBBEANCOM', 'HEYZO', '10MUSUME']
    for studio in studio_patterns:
        if studio in filename_upper:
            metadata['studio_info'] = studio
            break
    
    return metadata


def standardize_uncensored_filename(uncensored_id: str, metadata: Dict[str, Any]) -> str:
    """
    标准化无码文件名
    
    :param uncensored_id: 无码ID
    :param metadata: 元数据信息
    :return: 标准化的文件名（不含扩展名）
    """
    # 基础格式：保持原始ID格式
    base_name = uncensored_id
    
    # 添加后缀
    suffix_parts = []
    
    # 4K标记
    if metadata.get('is_4k', False):
        suffix_parts.append('4K')
    
    # CD分段标记
    if metadata.get('cd_number'):
        suffix_parts.append(f"CD{metadata['cd_number']}")
    
    # 字幕标记
    if metadata.get('has_subtitle', False):
        suffix_parts.append('C')
    
    # 组合最终文件名
    if suffix_parts:
        final_name = f"{base_name}-{'-'.join(suffix_parts)}"
    else:
        final_name = base_name
    
    return final_name.upper()


def validate_uncensored_result(standardized_name: str) -> bool:
    """
    验证无码标准化结果 - 支持数字格式和系列名格式
    
    :param standardized_name: 标准化后的文件名
    :return: 验证是否通过
    """
    # 系列名格式验证
    series_pattern = r'^(HEYZO|CARIBBEANCOM|1PON|10MUSUME)-\d+(?:-(?:4K|CD\d+|C))*$'
    if re.match(series_pattern, standardized_name, re.IGNORECASE):
        return True
    
    # 数字格式验证：支持两种分隔符 _ 或 -
    number_pattern = r'^\d{6}[-_]\d+(?:-(?:4K|CD\d+|C))*$'
    
    return bool(re.match(number_pattern, standardized_name))



def process_uncensored_filename(original_filename: str, cleaned_filename: str) -> Optional[Tuple[str, Dict[str, Any]]]:
    """
    处理无码文件名的主函数 - 完整流水线
    
    :param original_filename: 原始文件名
    :param cleaned_filename: 清理后的文件名
    :return: (标准化文件名, 元数据) 或 None
    """
    # 步骤1: 检测是否为无码类型
    is_uncensored, uncensored_id = detect_uncensored_type(cleaned_filename)
    
    if not is_uncensored or not uncensored_id:
        return None
    
    # 步骤2: 提取元数据
    metadata = extract_uncensored_metadata(cleaned_filename)
    metadata['video_type'] = 'UNCENSORED'
    metadata['extracted_id'] = uncensored_id
    metadata['original_filename'] = original_filename
    
    # 步骤3: 标准化文件名
    standardized_name = standardize_uncensored_filename(uncensored_id, metadata)
    
    # 步骤4: 验证结果
    if not validate_uncensored_result(standardized_name):
        return None
    
    metadata['is_valid'] = True
    
    return standardized_name, metadata


def batch_process_uncensored_filenames(filename_list: List[Tuple[str, str]]) -> List[Tuple[str, Optional[str], Optional[Dict[str, Any]]]]:
    """
    批量处理无码文件名
    
    :param filename_list: [(原始文件名, 清理后文件名), ...]
    :return: [(原始文件名, 标准化文件名或None, 元数据或None), ...]
    """
    def process_single(filename_pair: Tuple[str, str]) -> Tuple[str, Optional[str], Optional[Dict[str, Any]]]:
        """处理单个文件名的映射函数"""
        original, cleaned = filename_pair
        result = process_uncensored_filename(original, cleaned)
        
        if result:
            standardized, metadata = result
            return original, standardized, metadata
        else:
            return original, None, None
    
    # 使用函数式编程的map进行批量处理
    return list(map(process_single, filename_list))




# 导出的函数式接口
__all__ = [
    "detect_uncensored_type",
    "process_uncensored_filename",
    "batch_process_uncensored_filenames", 
    "validate_uncensored_result"
]